package com.starblink.basic.style.view.behavior

import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.widget.OverScroller
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.ViewCompat
import com.google.android.material.appbar.AppBarLayout
import java.lang.reflect.Field

/**
 * AppBar 滚动时抖动异常处理
 *
 * create by yuanl at 2021
 */
class AppBarLayoutFixedBehavior @JvmOverloads constructor(
    context: Context? = null,
    attrs: AttributeSet? = null
) : AppBarLayout.Behavior(context, attrs) {

    /**
     * 是否跳过嵌套拦截
     */
    private var skipNestedIntercept = false


    override fun onNestedScroll(
        coordinatorLayout: CoordinatorLayout,
        child: AppBarLayout,
        target: View,
        dxConsumed: Int,
        dyConsumed: Int,
        dxUnconsumed: Int,
        dyUnconsumed: Int,
        type: Int,
        consumed: IntArray
    ) {
        super.onNestedScroll(
            coordinatorLayout,
            child,
            target,
            dxConsumed,
            dyConsumed,
            dxUnconsumed,
            dyUnconsumed,
            type,
            consumed
        )
        stopNestedScrollIfNeeded(dyUnconsumed, child, target, type)
    }

    override fun onNestedPreScroll(
        coordinatorLayout: CoordinatorLayout,
        child: AppBarLayout,
        target: View,
        dx: Int,
        dy: Int,
        consumed: IntArray,
        type: Int
    ) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
        stopNestedScrollIfNeeded(dy, child, target, type)
    }

    private fun stopNestedScrollIfNeeded(dy: Int, child: AppBarLayout, target: View, type: Int) {
        if (type == ViewCompat.TYPE_NON_TOUCH) {
            val currOffset = topAndBottomOffset
            if (dy < 0 && currOffset == 0 || dy > 0 && currOffset == -child.totalScrollRange) {
                ViewCompat.stopNestedScroll(target, ViewCompat.TYPE_NON_TOUCH)
            }
        }
    }

    override fun onStartNestedScroll(
        parent: CoordinatorLayout,
        child: AppBarLayout,
        directTargetChild: View,
        target: View,
        nestedScrollAxes: Int,
        type: Int
    ): Boolean {
        return if (skipNestedIntercept) {
            false
        } else super.onStartNestedScroll(
            parent,
            child,
            directTargetChild,
            target,
            nestedScrollAxes,
            type
        )
    }

    override fun onInterceptTouchEvent(
        parent: CoordinatorLayout, child: AppBarLayout, ev: MotionEvent
    ): Boolean {
        if (skipNestedIntercept) {
            return false
        }
        //防止fling时，AppBarLayout页面抖动
        if (ev.action == MotionEvent.ACTION_DOWN) {
            val scroller = getSuperSuperField(this)
            if (scroller is OverScroller) {
                scroller.abortAnimation()
            }
        }
        return super.onInterceptTouchEvent(parent, child, ev)
    }

    private fun getSuperSuperField(paramClass: Any): Any? {
        val field: Field
        var `object`: Any? = null
        try {
            var behavior: Class<*>? = paramClass.javaClass
            while (behavior != AppBarLayout.Behavior::class.java) {
                behavior = behavior!!.superclass
                if (behavior == null) {
                    return null
                }
            }
            val headerBehavior = behavior.superclass.superclass
            field = headerBehavior.getDeclaredField("scroller")
            field.isAccessible = true
            `object` = field[paramClass]
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return `object`
    }

    /**
     * 设置跳过嵌套拦截
     * @param skipNestedIntercept
     */
    fun setSkipNestedIntercept(skipNestedIntercept: Boolean) {
        this.skipNestedIntercept = skipNestedIntercept
    }

    companion object {
        private const val TAG = "FixedBehavior"
    }
}